/*
 * @Author: zuimo
 * @Date: 2020-11-23 08:58:37
 * @LastEditTime: 2020-11-27 16:44:39
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \m-version-javaf:\demo\dataStruct\src\ts\LinkList.ts
 */


 class LinkNode {
    value: any
    next: LinkNode
    constructor(element) {
        this.value = element;
        this.next = null;
    }
}

const defaultEquals = (a, b) => {
    return a == b
}

 class LinkedList {
    private count: number;  // linklist lenght
    private head: LinkNode; // head pointer
    private equals;

    constructor(userEquals?) {
        this.head = null;
        this.count = 0;
        this.equals = userEquals || defaultEquals
    }

    // push(element)
    push(element) {
        const node = new LinkNode(element)
        if (this.isEmpty()) {
            this.head = node
        } else {
            let current = this.head;
            while (current.next !== null) {
                current = current.next
            }
            current.next = node;
        }
        this.count++
    }
    // insert(element, position)
    insert(element, pos) {
        if (pos >= 0 && pos <= this.count) {

            const node = new LinkNode(element)
            //  insert head
            if (pos == 0) {
                node.next = this.head;
                this.head = node
            } else {
                let current = this.head;
                let count = 0;
                while (current.next !== null && count < pos - 1) {
                    current = current.next
                    count++
                }
                node.next = current.next;
                current.next = node
            }
        }

        this.count++
    }
    // getElementAt(index)：返回链表中特定位置的元素。如果链表中不存在这样的元素，则undefined。
    getElementAt(pos: number) {
        if (pos < 0 || pos > this.count) {
            return void (0)
        }
        let i = 0;
        let current = this.head;
        for (; i < pos; i++) {
            current = current.next
        }
        return current
    }
    // remove(element)：从链表中移除一个元素。
    remove(element) {
        if (element === void (0) || element === null) {
            return void (0)
        }
        let current = this.head;
        if (current.value == element) {
            this.head = current.next;
            return void (0)
        }
        while (current.next !== null && !this.equals(current.next.value, element)) {
            current = current.next;
        }
        current.next = current.next.next
        return void (0)
    }
    // indexOf(element)
    indexOf(element) {
        if (element === void (0) || element === null) {
            return -1
        }
        let index = 0
        let current = this.head;
        while (current.next !== null && !this.equals(current.value, element)) {
            current = current.next;
            index++
        }
        let resultIndex = index
        if (current.next === null &&  !this.equals(current.value, element)) {
            resultIndex = -1
        }
        return resultIndex
    }
    // removeAt(position)：从链表的特定位置移除一个元素。
    removeAt(pos: number) {
        if (pos < 0 || pos > this.count) {
            return void (0)
        }
        let i = 0;
        let current = this.head;
        for (; i < pos - 1; i++) {
            current = current.next
        }
        current.next = current.next.next
        return void (0)
    }
    // isEmpty()：如果链表中不包含任何元素，返回true，如果链表长度大于0则返回false。
    isEmpty() {
        return this.size() === 0
    }
    // size()：返回链表包含的元素个数，与数组的length属性类似。
    size() {
        return this.count
    }

    printf2Arr():Array<any> {
        let linkArr = [];

        let current = this.head;
        while (current !== null) {
            linkArr.push(current)
            current = current.next;

        }
        return linkArr

    }

}




const list = new LinkedList();

list.push(1)
list.push(2)
list.push(3)
list.push(4)
list.insert(5,1)





console.log(list.removeAt(2))

console.log(list.printf2Arr())


